home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
bit
/
src
/
measure.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
5KB
|
229 lines
/*
* $Id: measure.c,v 0.91 1994/02/20 00:53:26 zhao Pre-Release $
*
*. This file is part of BIT shareware package. After the two weeks of
* free evaluation period, you are encouraged (required) to register
* your copy for a small registration fee, which is $35 for personal use
* and $50 for commercial, government and institutional use.
*
* Copyright(c) 1993, 1994 by T.C. Zhao.
* All rights reserved.
*
* Permission to use, copy, and distribute this software in its entirety
* for non-commercial purposes is hereby granted, provided that the
* above shareware and copyright notices and this permission notice
* appear in all copies and their documentation.
*
* This software may be modified for your own use, but modified versions
* may not be distributed without prior consent of the author.
*
* This software is provided "as is" without expressed or implied
* warranty of any kind.
*
*.
*
* Measure intensities along a line. Assuming square pixels, and distances
* are in terms of pixel-pixel distance.
*/
#include "bit.h"
#include "dmalloc.h"
#include "extern.h"
/* get the RGB intensity and Grayscale or colorindex */
#include <math.h>
#include "lookup.h"
#define PI 3.1415926
/* given a line, get theta between -180 and 180 */
void
get_theta(int w, int h, float *theta)
{
if ((Abs(w) + Abs(h)) < 5)
return;
if (w == 0)
{
*theta = (h > 0) ? 90.0 : -90.0;
}
else if (h == 0)
{
*theta = (w > 0) ? 0.0 : 180.0;
}
else
{
*theta = atan2(h, w) * 180.0 / PI;
}
}
static float *yy[4], *xx;
static float ymin[] =
{
0, 0, 0, 0
};
static float ymax[] =
{
PCMAX - 1, PCMAX - 1, PCMAX - 1, PCMAX - 1
};
static void
get_lmem(int n)
{
yy[0] = malloc(sizeof(float) * n);
yy[1] = malloc(sizeof(float) * n);
yy[2] = malloc(sizeof(float) * n);
yy[3] = malloc(sizeof(float) * n);
xx = malloc(sizeof(float) * n);
}
static void
free_lmem(void)
{
free(yy[0]);
free(yy[1]);
free(yy[2]);
free(yy[3]);
free(xx);
}
/*
* Get intensity along theta and show it. X-axis will be the distance (in
* pixels) along theta. No interpolation is done
*/
static void
scan_int(IPTR im, float theta, int x, int y, int w, int h)
{
double dx, dy;
double st = sin(theta * PI / 180.0), tt = tan(theta * PI / 180.0);
int aw, ah;
int ix, iy, ii, iimax;
rgba_t pix;
ci_t ci;
int r, g, b;
char title[40];
aw = Abs(w);
ah = Abs(h);
tt = Abs(tt);
iimax = Max(aw, ah);
get_lmem(iimax + 1);
/* always try to get maximum no. */
for (ii = 0; ii < iimax; ii++)
{
if (aw > ah)
{ /* move horizontally */
dx = (w > 0) ? ii : -ii;
dy = tt * ii;
dy = (h > 0) ? dy : -dy;
}
else
{ /* move vertically */
dy = (h > 0) ? ii : -ii;
dx = (w == 0) ? 0 : (ii / tt);
dx = (w > 0) ? dx : -dx;
if (w > 0)
dx = Abs(dx);
}
xx[ii] = (h == 0) ? dx : (dy / st);
ix = (x - im->xi + dx);
iy = (y - im->yi + dy);
if (IS_CPACK(im))
{
pix = ((rgba_t **) im->mraster)[iy][ix];
Unpack(pix, r, g, b);
yy[0][ii] = r;
yy[1][ii] = g;
yy[2][ii] = b;
yy[3][ii] = RGB2GRAY(r, g, b);
}
else
{ /* ci_t */
ci = ((ci_t **) im->mraster)[iy][ix];
ci &= (PCMAX - 1);
yy[0][ii] = im->cmap->ct[0][ci];
yy[1][ii] = im->cmap->ct[1][ci];
yy[2][ii] = im->cmap->ct[2][ci];
yy[3][ii] = ci;
}
}
/* show whatever we've got */
set_chart4_style(FL_LINE_XYPLOT);
set_chart4_text("Red", "Green", "Blue", IS_CI(im) ? "Colorindex" : "Gray");
sprintf(title, "t=%.1f", theta);
for (ix = 0; ix < 4; ix++)
ymax[ix] = IS_CI(im) ? (im->cmap->colors - 1) : (PCMAX - 1);
set_chart4_ybounds(ymin, ymax);
show_chart4(title, xx, yy, ii);
free_lmem();
}
static int bdcolor = 1;
static int
handle_pup(void)
{
static long phandle = -1;
int ret = 0;
if (phandle < 0)
phandle = defpup("LinearScan%t|Help|LColor|Return");
switch (dopup(phandle))
{
case 1:
help_cb(0, HELP_LSCAN);
break;
case 2:
rubber_hide();
++bdcolor;
bdcolor %= over_pup_colors;
rubber_show(bdcolor);
break;
case 3:
ret = 1;
break;
}
return ret;
}
int
img_measure(IPTR im)
{
long dev;
short val;
int x, y, w, h, done = 0;
float t;
set_rubber_bounds(1, im->xi, im->yi, im->w, im->h);
set_rubber_obj(RB_LINE);
x = (im->xi + im->xf) / 2;
y = (im->yi + im->yf) / 2;
w = h = Min(im->w, im->h) / 2;
while (!done)
{
dev = rubber_info(win_id, &val, &x, &y, &w, &h, bdcolor, 15);
/* note: rubber_info returns the no. of pixels, not distance. */
get_theta((w - 1), (h - 1), &t);
switch (dev)
{
case REDRAW:
if (val == win_id)
repaint(im, val);
break;
case ESCKEY:
done = val;
break;
case MENUBUTTON:
done = (val && handle_pup());
break;
default:
done = (dev == KEYBD && val == 27);
if (!done && (dev == LEFTMOUSE || dev == MIDDLEMOUSE) && val)
scan_int(im, t, x, y, (w - 1), (h - 1));
break;
}
}
rubber_finish();
return 0;
}